筆記目錄

Skip to content

ASP.NET Core 命名空間衝突問題

TLDR

  • 專案名稱若包含 SystemMicrosoft 等關鍵字,極易導致命名空間解析衝突。
  • Razor View 檔案在編譯時會產生額外的全域 using 指令,即使關閉 C# 的 Global Using Directives 功能,衝突依然存在。
  • 衝突發生時,編譯器會嘗試從專案自定義的命名空間下尋找系統類別(例如 TestNameSpace.System.Threading),導致找不到型別的錯誤。
  • 解決方案為避免使用關鍵字作為專案名稱;若已發生,需調整 _ViewImports.cshtml_ViewStart.cshtml 中的命名空間設定。

命名空間衝突的問題情境

什麼情況下會遇到這個問題:當開發者將專案名稱命名為包含 SystemMicrosoft 等關鍵字(例如將專案命名為 TestNameSpace.System)時,會導致編譯失敗。

在 Razor View 檔案中,編譯器會出現大量錯誤。錯誤訊息通常顯示為「命名空間 'TestNameSpace.System' 中沒有類型或命名空間 'Threading'」,這是因為編譯器將 System.Threading 誤判為專案自定義命名空間下的子項目,而非引用系統的 System.Threading

razor compilation errors

Global Using Directives 的影響

什麼情況下會遇到這個問題:使用 .NET 6 以上版本,並啟用隱含全域 using 功能時。

C# 10 引入了 Global Using Directives 功能,專案建置後會在 obj 資料夾下產生 {專案名稱}.GlobalUsings.g.cs 檔案。該檔案會自動加入系統預設的命名空間,例如:

csharp
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

若專案名稱與 System 衝突,編譯器在處理這些全域引用時會產生歧義。

Razor View 的編譯機制與修正建議

什麼情況下會遇到這個問題:即便關閉了 Global Using Directives 或使用 .NET 5 版本,Razor 檔案依然無法編譯。

研究發現,Razor 檔案的編譯過程會產生額外的 .g.cs 檔案,其中包含預設的 using 設定。這些設定並非完全依賴 Global Using Directives,而是由 Razor 引擎在編譯時寫入。

若要解決此問題,需檢查 _ViewStart.cshtml_ViewImports.cshtml 中的命名空間定義。建議透過 @namespace 指令明確指定命名空間,避免與系統關鍵字衝突:

csharp
@using TestNamespace.Sys.Web
@namespace TestNamespace.Sys.Web.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

TIP

在 .NET 5 中,編譯產生的 Razor 檔案位於 obj\Debug\net5.0\Razor\Pages\ 目錄下。在 .NET 6 以上版本,編譯產生的中間檔案路徑可能有所變動。

結論

為避免 ASP.NET Core 專案發生不可預期的命名空間解析錯誤,建議在建立專案時,專案名稱應避免使用 SystemMicrosoft 等關鍵字。

異動歷程

  • 2023-01-09 初版文件建立。